# 《R语言简明教程》第二课练习

## 数据的读取和基本处理
### 常用数据的类型
# - .csv
# - .txt
# - .xlsx

### 内置函数
# - `read.csv()`
# - `read.table()`
# - `readLines()`
# - `read.delim()`
# - `readr`包
# - `openxlsx`包
# - `readxl`包


## 向量和字符串操作

# 1. 输入 Vietnam, India, India, South Africa, Congo, China, Japan, Korea, Russia, France, China, Germany, USA, Canada, Australia, New Zealand 组成向量
dat <- readLines("/Users/jinlong/Desktop/lesson02/countries.txt")

# 2. 向量应该是什么类型？
# character

# 3. 一共有多少个国家？
country_unique <- unique(dat)
length(country_unique)

# 4. 哪一个国家出现的次数最多？
table(dat)

# 5. 哪个国家包含的字母最多？
nc <- nchar(dat)
dat[nc == max(nc)]


# 6. 怎样将名称全部转换为小写？
tolower(dat)

# 7. 全部转换为大写
toupper(dat)

# 8. 将向量保存在纯文本文件中
write.csv(dat, "countries2.csv")


# 9. 将国家按照字母顺序排列
sort(dat)

# 10. 将各个国家按照各洲名称按照字母顺序排列
setwd("/Users/jinlong/Desktop/lesson02")
countries2 <- read.csv("countries2.csv", header = TRUE)
countries2[order(countries2$continent),]

# 11. 哪个国家名称中有空格？
dat[grepl(pattern = " ", dat)]

# 12. 怎样去掉重复的国家？
unique(dat)

# 13. 提取第三到第五个国家的名称
dat[3:5]

# 14. 将每个国家按照原来出现的次数增加一倍
times <- table(dat)
rep(names(times), times*2)

## 数据框的基本操作

# 成绩单数据
# 
# 1. 将成绩单导入R
setwd("/Users/jinlong/Desktop/lesson02")
library(openxlsx)
dat <- read.xlsx("record_sheet.xlsx")

# 2. 显示前六行
head(dat)

# 3. 显示后六行
tail(dat)

# 4. 有多少行？
nrow(dat)

# 5. 多少列?
ncol(dat)

# 6. 班上有多少个同学？有多少男同学，多少女同学？
nrow(dat)
table(dat$gender)

# 7. 有多少人及格，有多少人不及格？
table(dat$score >= 60)

# 8. 提取名单
dat$first_name
dat$last_name

# 9. 提取成绩数据的那一列

# 10. 男同学和女同学的平均分分别是多少？
dat_m <- subset(dat, gender == "M")
mean(dat_m$score)

dat_f <- subset(dat, gender == "F")
mean(dat_f$score)

# 11. 全班最高分、最低分、平均分、中位数分别是多少？
max(dat$score)
min(dat$score)
mean(dat$score)
median(dat$score)

# 12. 增加一列`attend`，表示考试出席情况， `John`没有出席
attend <- rep(T, nrow(dat))
dat2 <- cbind(dat, attend)
dat2$attend[1] <- F

dat2$attend[dat$first_name == "John"] <- F


# 13. 将`John`的成绩改为NA
dat2$score[dat$first_name == "John"] <- NA

# 14. `subset`只取男同学，生成单独的成绩表

# 15. `subset`只取女同学，生成单独的成绩表

# 16. 提取数据框的第一列
dat2[,1]
# 17. 提取第二列到第三列
dat2[,2:3]

# 18. 提取行名
row.names(dat2)

# 19. 提取列名
colnames(dat2)

# 20. 提取`first_name`
dat2$first_name
dat2[,1]
dat2[,"first_name"]

# 21. 提取`last_name`
dat2[,"last_name"]

# 22. 生成`full_name`并添加到一列
paste(dat2[,"first_name"], dat2[,"last_name"], sep = " ")

# 23. 保存为excel
openxlsx::write.xlsx(dat2, "modified_score_sheet.xlsx")

# 24. 保存为csv文件
write.csv(dat2, "modified_score_sheet.csv")

## 向量的操作
# 1. 生成1-20的向量
aaa <- 1:20

# 2. 将单数标注为`odd`, 双数标注为`even`
bbb <- aaa %% 2
bbb[bbb == 1] <- "odd"
bbb[bbb == 0] <- "even"
bbb
names(aaa) <- bbb

# 3. 将15替换为NA
# aaa[15] <- NA
aaa[aaa == 15] <- NA

# 4. 将NA替换为10
aaa[is.na(aaa)] <- 10
aaa

# 5. 将数随机排列，提取第一个，提取最后一个，提取倒数第二个，提取倒数第六个
sample(aaa)
aaa[1]
aaa[length(aaa)]
aaa[length(aaa)-1]
aaa[length(aaa)-5]

# 6. 随机提取5个数
sample(aaa, size = 5)
# 7. 将数据随机排列
aaa[sample(1:20)]

# 8. 最大的数，出现在第几位？
aaa2 <- sample(aaa)
which(aaa2 == max(aaa2))

# 9. 最小的数，出现在第几位？
which(aaa2 == min(aaa2))

# 10. 平均数是多少？
mean(aaa2)
# 11. 哪些数比平均值大？
which(aaa2 > mean(aaa2))

# 12. 所有数的和是多少？
sum(aaa2)

# 13. 将这20个数，生成4行，5列的矩阵
dim(aaa2) <- c(4, 5)
aaa2

# 14. 将矩阵转置，行变成列，列变成行
t(aaa2)

# 15. 计算各列的平均数
apply(aaa2, 2, FUN = "mean")


# 16. 计算各列的和
apply(aaa2, 2, FUN = "sum")


# 17. 将各列标准化 `(x - x_mean)/x_sd`
apply(aaa2, 2, FUN = "scale")
scale(aaa2)

# 18. 将matrix转换为vector
as.vector(aaa2)
# 19. 将数值转换为字符串类型
aaa3 <- as.character(aaa2)
is.character(aaa3)

## 程序包中data.frame以及list的基本操作

# 1. 导入vegan程序包
library(vegan)

# 2. 如未安装，安装程序包

# 3. 打开vegan的帮助文件，以及函数列表
# 4. 打开dune.env的帮助
# 5. 查看dune数据的类型，dune.env的类型
data(dune)
class(dune)

# 6. dune包含有多少行，多少列？
dim(dune)

# 7. 提取dune各列的名称，每一列代表什么？
colnames(dune)

# 8. 提取dune的行数，每一行代表什么？
row.names(dune)

# 9. dune数据的数字是什么意思？为什么有那么多0？

# 10. dune.env各列是什么？
data(dune.env)
head(dune.env)

# 11. dune和dune.env是怎么匹配的？

# 12. dune.env有几种management管理方式？
unique(dune.env$Management)

# 13. 能提取management为NM的行吗？
dune.env[dune.env$Management == "NM",]
subset(dune.env, Management == "NM")

# 14. 如何将dune.env和dune组合成一个list?
sss <- list(d1 = dune.env, d2 = dune)
length(sss)

# 15. 如何提取list中的dune.env或者dune？
sss[[1]]
sss[[2]]
names(sss)
sss$d1
sss$d2
# 16. 如何给list中的对象命名？
sss <- list(d1 = dune.env, d2 = dune)
names(sss) <- c("d3", "d4")
sss


